Skip to content

Fix remaining cpp/ CodeQL code-scanning alerts in Windows build-tools#762

Merged
vharseko merged 4 commits into
OpenIdentityPlatform:masterfrom
vharseko:fix-codeql-cpp-remaining
Jul 27, 2026
Merged

Fix remaining cpp/ CodeQL code-scanning alerts in Windows build-tools#762
vharseko merged 4 commits into
OpenIdentityPlatform:masterfrom
vharseko:fix-codeql-cpp-remaining

Conversation

@vharseko

@vharseko vharseko commented Jul 24, 2026

Copy link
Copy Markdown
Member

Fixes the six remaining open cpp/* code-scanning alerts (#55, #57, #58, #59, #73, #75):

Additionally, per review: the isrunning subcommand of opendj_service.exe now reports the actual server state instead of discarding it — it prints true/false and mirrors the return-code scheme of serviceState (0 = running, 1 = not running, 2 = cannot determine). Nothing in the repository invokes this subcommand, so the changed exit codes break no callers.

@vharseko vharseko added the security Security fixes / CodeQL code-scanning alerts label Jul 24, 2026
@vharseko
vharseko requested a review from maximthomas July 24, 2026 15:45
Comment thread opendj-server-legacy/src/build-tools/windows/winlauncher.c Fixed

@maximthomas maximthomas left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified that all six targeted alerts (55, 57, 58, 59, 73, 75) are open on master at exactly the lines this PR touches, and that the merge ref has zero open cpp/* alerts — the goal is achieved. (The cpp/uninitialized-local alert introduced by afc3440a is already closed by 817f2b40; no action needed.) CI genuinely exercises every touched path: start-ds.bat/stop-ds.bat, windows-service.bat --enableService + net start/net stop, and an MSI install into a path with spaces.

Two comments assert a security property that Windows does not provide, and there is one silent-wrong-directory edge case.

Permission comments are factually wrong (Medium)

Neither file-creation change restricts permissions; both are pure alert suppression.

opendj-server-legacy/src/build-tools/windows/common.c:

  // Create the log file readable and writable by the owner only, while
  // keeping the shareable append behavior that fopen provides.

Per _sopen_s docs, pmode only sets the read-only attribute at creation — it never touches the DACL: "_S_IREAD | _S_IWRITE — Reading and writing permitted. […] In the Windows operating system, all files are readable; it isn't possible to give write-only permission. Therefore, the modes _S_IWRITE and _S_IREAD | _S_IWRITE are equivalent." So this is byte-for-byte the same accessibility as the previous fopen(logFile, "a").

opendj-server-legacy/src/build-tools/windows/winlauncher.c:

    // fopen_s creates the file readable and writable by the owner only,
    // unlike fopen which would create it world-writable.

Both halves are wrong. fopen does not create world-writable files on Windows — the DACL is inherited from the parent directory — and the fopen_s docs say nothing about restricted permissions. The one documented difference is the opposite of an improvement: "The fopen_s and _wfopen_s functions can't open a file for sharing. If you need to share the file, use _fsopen or _wfsopen […] use _SH_DENYNO for read/write sharing."

The pid file is written and closed immediately, so losing sharing is harmless in practice. Please just correct both comments and the PR description to say what is actually happening — e.g. "cpp/world-writable-file-creation models POSIX creation modes and does not apply to Windows ACLs; use the _s variants to satisfy the query". Otherwise a future maintainer will believe these files are owner-restricted when they are exactly as accessible as before. Dismissing #73/#75 as not-applicable-on-Windows is the equally valid alternative, and avoids the fopen_s sharing regression.

getCanonicalDirectoryPath silently accepts a drive-relative path (Low)

GetFullPathName docs: "If you specify U: the path returned is the current directory on the U:\ drive."

ConfigureWindowsService.getServerRoot() strips a trailing File.separator, so a drive-root install yields the string "C:". That resolves to the process's current directory on C: (for a service, C:\Windows\System32), which passes isExistingDirectory() — so the tool proceeds against an unrelated directory instead of failing. Unlikely layout, but it is the one path where the new helper silently succeeds with the wrong answer.

In opendj-server-legacy/src/build-tools/windows/common.c:

  // "C:" is drive-relative: it would resolve to the current directory on
  // that drive rather than to its root.
  if ((strlen(path) == 2) && (path[1] == ':'))
  {
    debugError("The path '%s' is drive-relative.", path);
    return NULL;
  }

Nits

  • Misleading GetLastError(): on the length >= MAX_PATH branch the call did not fail — the docs return the required buffer size there, and GetLastError is only meaningful when the return value is 0. Split the two branches so the log does not report a stale error code.
  • setInstanceDir should be static: it is file-local with no prototype in service.h, and service.obj links against common.obj.
  • Inverted condition duplicates the error branch: else if (setInstanceDir(...)) { … } else { returnCode = -1; } repeats returnCode = -1; five times in service.c main. else if (!setInstanceDir(argv[2])) { returnCode = -1; } else { … } reads better and shrinks the diff.
  • Duplicated blocks in winlauncher.c: the start and stop error handlers are byte-identical; both subcommands need argv[2] canonicalized, so hoisting the call above the branch removes ~14 lines.
  • _instanceDir not reset to NULL after free(): pre-existing, but the PR touches all five sites.
  • isrunning discards its result (pre-existing): the added comment says "Check the server lock file to determine if the server is running", but running is never used — the subcommand returns 0 whenever the lock file is merely readable. Worth a separate fix.

@vharseko

Copy link
Copy Markdown
Member Author

@maximthomas Thanks for the thorough review — all points addressed in b4ee601 and 7473104.

Permission comments: you are right, neither change affects the DACL. Both comments now state what actually happens — cpp/world-writable-file-creation models POSIX creation modes that do not exist on Windows (the ACL is inherited from the parent directory either way), and the _s variants with an explicit mode merely satisfy the query. The PR description is updated accordingly. Kept the code rather than dismissing #73/#75 so the alerts stay closed by the default query suite; the sharing fopen_s denies is irrelevant for the pid file, which is written and closed immediately.

Drive-relative paths: getCanonicalDirectoryPath now rejects two-character X: paths up front with your suggested guard, so a drive-root install fails loudly instead of silently operating on the process's current directory.

Nits — all taken:

  • The GetFullPathName error branches are split: GetLastError() is only logged when the call actually failed; the too-long branch reports the required length instead.
  • setInstanceDir is now static.
  • The five service.c dispatch branches use the inverted condition, dropping the duplicated trailing else { returnCode = -1; } blocks.
  • The byte-identical start/stop handlers in winlauncher.c are merged, with canonicalization hoisted above the dispatch.
  • _instanceDir is freed and reset via a new freeInstanceDir() helper at all five sites.

isrunning: fixed here as well rather than in a separate PR. The subcommand now uses the running flag it previously discarded: it prints true/false and mirrors the serviceState return-code scheme (0 = running, 1 = not running, 2 = cannot determine). Nothing in the repository invokes isrunning, so the changed exit codes break no callers; isServerRunning itself is untouched since its other callers treat SERVICE_RETURN_ERROR as failure.

@vharseko
vharseko merged commit a6d5d2d into OpenIdentityPlatform:master Jul 27, 2026
28 of 29 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

security Security fixes / CodeQL code-scanning alerts Windows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants